using Microsoft.Win32;
using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace DynamicConfigurationManager.ConfigMapAttributes
{
    /// <summary>
    /// RegistryValueRegEx compares the attribute value to a registry value.
    /// </summary>
    internal class RegistryValueRegEx : IConfigMapAttribute
    {
        private static readonly Dictionary<string, string> mappings = new Dictionary<string, string>
        {
            {"HKLM", "HKEY_LOCAL_MACHINE"},
            {"HKCU", "HKEY_CURRENT_USER"},
            {"HKCC", "HKEY_CURRENT_CONFIG"},
            {"HKCR", "HKEY_CLASSES_ROOT"},
            {"HKU", "HKEY_USERS"}
        };

        public bool Execute( string configMapAttribute )
        {
            var namevalue = configMapAttribute.Split( "=".ToCharArray(), 2 );
            if( namevalue.Length != 2 )
            {
                return false;
            }

            var regPath = namevalue[0];
            var valueRegEx = namevalue[1];

            if( string.IsNullOrWhiteSpace( regPath ) || string.IsNullOrWhiteSpace( valueRegEx ) )
            {
                return false;
            }

            LogHelper.Append( "RegistryValueRegEx: matching {0} to {1}", regPath, valueRegEx );

            foreach( var mapping in mappings )
            {
                regPath = regPath.Replace( mapping.Key, mapping.Value );
            }

            // get the key (parent of the name) and value name
            var lastSlash = regPath.LastIndexOf( '\\' );
            var regKey = regPath.Substring( 0, lastSlash );
            var regName = regPath.Substring( lastSlash + 1 );

            // get the registry value
            var val = Registry.GetValue( regKey, regName, null );
            LogHelper.Append( "RegistryValueRegEx: registry key {0} value {1} is '{2}'", regKey, regName, val );
            if( val != null )
            {
                var re = new Regex( valueRegEx, RegexOptions.IgnoreCase );
                return re.IsMatch( val.ToString() );
            }

            return false;
        }
    }
}